public with sharing class Callidus_PlanApprovalRejectionByManager
{
	private String currentPageURL;
	private ID salesContractId;
	private ID processInstanceWorkItemId;
	private Sales_Contract__c[] scList;
	
    private DataAccessControlUtil dacu = null;
    private Map<String, Schema.SObjectField> scSObjectFieldMap = new Map<String, Schema.SObjectField>(); 
    private String constructSoql;
	public String back2PlanURL {
		get 
		{
			if(Apexpages.currentPage().getParameters().get('rpg') != null && Apexpages.currentPage().getParameters().get('rpg') == '1')
				return '/apex/Sales_Contract_Custom_Page_For_RM?id='+salesContractId;
			else
				return '/apex/Sales_Contract_CustomPage?id='+salesContractId;
		}
	}
	
	public Sales_Contract__c sContract {get; set;}
	public Sales_Contract__c sContractDup {get; set;}
	public String comments {get; set;}
	public String managerRejectComment {get; set;}
	
	public Callidus_PlanApprovalRejectionByManager()
	{
		PageReference pg = Apexpages.currentPage();
		currentPageURL = pg.getUrl();
		salesContractId = pg.getParameters().get('id');
		processInstanceWorkItemId = pg.getParameters().get('pid');
        dacu = new DataAccessControlUtil();
        SObject scObj = new Sales_Contract__c();

        scSObjectFieldMap = dacu.getFieldMap(scObj);
        
        String[] expectedFields = new String[]{'id', 'name', 'plan_document_name__c', 'status__c', 'ownerid', 'Manager_Reject_reason__c', 'Manager_Reject_Comment__c', 'Comments__c'}; 
        
        Set<String> allowedFields = dacu.getAccessibleFields(scObj, scSObjectFieldMap, expectedFields);
        
        if(!allowedFields.isEmpty())
        {
            constructSoql = 'Select ';
            for(String roField: allowedFields)
            {
                constructSoql += roField+', ';
            }
            constructSoql = constructSoql.substring(0, constructSoql.length() - 2);
            constructSoql += '  from Sales_Contract__c where id = :salesContractId ';
            
            scList = Database.query(constructSoql);
            sContract = scList[0];
        }
	}
	
	public PageReference approve()
	{
		SObject scObj = new Sales_Contract__c();
        String message = dacu.isUpdateableObjectByUser(scObj);
        
        if(message.equalsIgnoreCase('success'))
        {       
	        String[] expectedFields = new String[]{'id', 'Comments__c'}; 
	        
	        Set<String> allowedFields = dacu.getAccessibleFields(scObj, scSObjectFieldMap, expectedFields);

	        if(!allowedFields.isEmpty())
	        {
	            constructSoql = 'Select ';
	            for(String roField: allowedFields)
	            {
	                constructSoql += roField+', ';
	            }
	            constructSoql = constructSoql.substring(0, constructSoql.length() - 2);
	            constructSoql += '  from Sales_Contract__c where id = :salesContractId ';
	            
	            scList = Database.query(constructSoql);
	            sContractDup = scList[0];
            
		        scObj = sContractDup;
	            if(scSObjectFieldMap.isEmpty())
	                scSObjectFieldMap = dacu.getFieldMap(scObj);
	        
	            //Note: Whenever a new Custom field has to be updated, add it to the below Set.
	            Set<String> expectedUpdateableFields = new Set<String>{'Comments__c'};
	            
	            //Store the expected updated fields and their values
	            Map<String, Object> fieldsValMap = new Map<String, Object>();
	            fieldsValMap.put('Comments__c', comments);
	            
	            //Get the filtered Fields that can be updated
	            Set<String> filteredFields = dacu.getFilteredUpdateableFields(scSObjectFieldMap, expectedUpdateableFields);
	            
	            //Update only fields with update permsission
	            for(String s: filteredFields)
	            {
	                scObj.put(s, (String)fieldsValMap.get(s));
	            }
	
	            if(!filteredFields.isEmpty())   
	            {
	                update scObj;
	            }
	        }
	        
		    Approval.ProcessWorkitemRequest prWkItem = new Approval.ProcessWorkitemRequest();
	    
	        prWkItem.setWorkitemId(processInstanceWorkItemId);
	
	        prWkItem.setComments(comments); 
	            
	        prWkItem.setAction('Approve'); 
	
		    Approval.ProcessResult prResult = Approval.process(prWkItem);
        }
		
    	PageReference pg = new PageReference(back2PlanURL);
    	
		return pg;
	}

	public PageReference reject()
	{
		if(sContract.Manager_Reject_Reason__c == null)
		{
			ApexPages.addMessage(new Apexpages.Message(ApexPages.severity.error, 'Select a Reject Reason.'));
			return null;
		}	
		
		if(managerRejectComment == null)
		{
			ApexPages.addMessage(new Apexpages.Message(ApexPages.severity.error, 'Enter Reject Comment.'));
			return null;
		}

		if(managerRejectComment != null && managerRejectComment.trim().length() == 0)
		{
			ApexPages.addMessage(new Apexpages.Message(ApexPages.severity.error, 'Enter Reject Comment.'));
			return null;
		}

        SObject scObj = new Sales_Contract__c();
        String message = dacu.isUpdateableObjectByUser(scObj);
        
        if(message.equalsIgnoreCase('success'))
        {       
	        String[] expectedFields = new String[]{'id', 'Manager_Reject_reason__c', 'Manager_Reject_Comment__c', 'Comments__c','Date_Rejected__c'}; 
	        
	        Set<String> allowedFields = dacu.getAccessibleFields(scObj, scSObjectFieldMap, expectedFields);

            if(!allowedFields.isEmpty())
	        {
	            constructSoql = 'Select ';
	            for(String roField: allowedFields)
	            {
	                constructSoql += roField+', ';
	            }
	            constructSoql = constructSoql.substring(0, constructSoql.length() - 2);
	            constructSoql += '  from Sales_Contract__c where id = :salesContractId ';
	            
	            scList = Database.query(constructSoql);
	            sContractDup = scList[0];
	            
		        sContractDup.Manager_Reject_Comment__c = managerRejectComment;
		        sContractDup.Manager_Reject_reason__c = sContract.Manager_Reject_Reason__c;
		        scObj = sContractDup;

		        if(scSObjectFieldMap.isEmpty())
	                scSObjectFieldMap = dacu.getFieldMap(scObj);
	        
	            //Note: Whenever a new Custom field has to be updated, add it to the below Set.
	            Set<String> expectedUpdateableFields = new Set<String>{'Manager_Reject_Comment__c', 'Comments__c', 'Date_Rejected__c'};
	            
	            //Store the expected updated fields and their values
	            Map<String, Object> fieldsValMap = new Map<String, Object>();
	            fieldsValMap.put('Comments__c', managerRejectComment);
	            fieldsValMap.put('Manager_Reject_Comment__c', managerRejectComment);
	            fieldsValMap.put('Date_Rejected__c', Datetime.now());
	            
	            //Get the filtered Fields that can be updated
	            Set<String> filteredFields = dacu.getFilteredUpdateableFields(scSObjectFieldMap, expectedUpdateableFields);
	            
	            //Update only fields with update permsission
	            for(String s: filteredFields)
	            {
	                if(!s.equalsIgnoreCase('Date_Rejected__c'))
	                    scObj.put(s, (String)fieldsValMap.get(s));
	                else
	                    scObj.put(s, (DateTime)fieldsValMap.get(s));
	            }
	
	            if(!filteredFields.isEmpty())   
	            {
	                update scObj;
	            }
	            
	            
	        }
	        
		    Approval.ProcessWorkitemRequest prWkItem = new Approval.ProcessWorkitemRequest();
	    
	        prWkItem.setWorkitemId(processInstanceWorkItemId);
	
	        prWkItem.setComments(sContract.Manager_Reject_Comment__c); 
	            
	        prWkItem.setAction('Reject'); 
	
		    Approval.ProcessResult prResult = Approval.process(prWkItem);
        }
		
    	PageReference pg = new PageReference(back2PlanURL);
    	
		return pg;
	}
}